package com.yswy.backstage.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yswy.backstage.service.SsoService;
import com.yswy.backstage.service.TgDeductionChildService;
import com.yswy.backstage.service.TgDeductionService;
import com.yswy.backstage.service.TgMediaAccountService;
import com.yswy.common.utils.StringUtils;
import com.yswy.domain.common.BasePojo;
import com.yswy.domain.entity.tf.TgDeduction;
import com.yswy.domain.entity.tf.TgDeductionChild;
import com.yswy.domain.entity.tf.TgMediaAccount;
import com.yswy.domain.entity.user.User;
import com.yswy.domain.framework.context.CurrentUserContext;
import com.yswy.domain.mapper.tf.TgDeductionMapper;
import com.yswy.domain.mapper.tf.TgMediaAccountMapper;
import com.yswy.domain.vo.dto.BaseFilter;
import com.yswy.domain.vo.gld.addOrUpate.TgDeductionAddOrUpdate;
import com.yswy.domain.vo.gld.addOrUpate.TgDeductionChildAddOrUpdate;
import com.yswy.domain.vo.gld.addOrUpate.TgMediaAccountAddOrUpdate;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import static com.yswy.backstage.utils.CrudUtils.selectCount;
import static com.yswy.common.constants.WarnMsgConstants.NULL_MSG;

@Slf4j
@Service
public class TgDeductionServiceImpl extends ServiceImpl<TgDeductionMapper, TgDeduction>
        implements TgDeductionService {
    @Autowired
    private SsoService ssoService;
    @Autowired
    private TgDeductionChildService tgDeductionChildService;

    @Override
    public Page<TgDeduction> pageTgDeduction(BaseFilter req) {
        Page<TgDeduction> pageTgDeduction = baseMapper.pageTgDeduction(req
                ,ssoService.isAdminToUserId(CurrentUserContext.getCurrentUser())
                , new Page<>(req.getPageNum() , req.getPageSize()) );
        return pageTgDeduction;
    }

    @Override
    public List<TgDeduction> listTgDeduction(Long tgDeductionId) {
        return baseMapper.listTgDeduction(ssoService.isAdminToUserId(CurrentUserContext.getCurrentUser())
                , tgDeductionId);
    }

    @Override
    public Boolean isExist(String identifier) {
        Integer count = count(new LambdaQueryWrapper<TgDeduction>()
                .eq(TgDeduction::getIdentifier , identifier)
                .eq(BasePojo::getIsDel , 0));
        if (count>0){
            return true ;
        }
        return false;
    }

    @Override
    @Transactional
    public void addOrUpadteTgDeduction(TgDeductionAddOrUpdate res) {
        User user = CurrentUserContext.getCurrentUser();


        Boolean isExist =  isExist(res.getIdentifier());
        TgDeduction tgDeduction = null ;
        if (res.getId() != null){
            //更新数据
            tgDeduction = getById(res.getId());
            Assert.state(null != tgDeduction && null != tgDeduction.getId(), NULL_MSG);
            BeanUtil.copyProperties(res, tgDeduction);
            BasePojo.setBase(user.getId().longValue(), false, tgDeduction);
            updateById(tgDeduction);
        }else {
            if (isExist){
                throw new IllegalStateException("配置已存在");
            }
            tgDeduction = new TgDeduction(res , user);
            save(tgDeduction);
        }

        //判断时间是否重叠
        List<TgDeductionChild> tgDeductionChildrens = new ArrayList<>();
        if (res.getTgDeductionChildAddOrUpdates() != null){
            for (TgDeductionChildAddOrUpdate child:
                    res.getTgDeductionChildAddOrUpdates()) {
                LocalTime startTime = LocalTime.parse(child.getStartTime());
                LocalTime endTime = LocalTime.parse(child.getEndTime());
                if (StringUtils.isEmpty(child.getStartTime())
                        || StringUtils.isEmpty(child.getEndTime())
                        || child.getProportion() == null){
                    throw new IllegalStateException("扣量参数不能为空");
                }
                if (endTime.isBefore(startTime)){
                    throw new IllegalStateException("结束时间不能大于开始时间");
                }

                if ( child.getProportion() >100){
                    throw new IllegalStateException("扣量比列不能大于100");
                }
                tgDeductionChildrens.add(new TgDeductionChild(child , tgDeduction.getId()));
            }
        }

        boolean isOverlap = checkOverlap(tgDeductionChildrens);
        if (isOverlap){
            throw new IllegalStateException("扣量时间不能重叠");
        }

        if (tgDeductionChildrens.size()>0){
            orderDeduction(tgDeductionChildrens);
            tgDeductionChildService.remove(new LambdaQueryWrapper<TgDeductionChild>()
                    .eq(TgDeductionChild::getTgDeductionId , tgDeduction.getId()));
            tgDeductionChildService.saveBatch(tgDeductionChildrens);
        }
    }

    @Override
    public void delTgDeduction(Long tgDeductionId) {
        User user = CurrentUserContext.getCurrentUser();
        Integer count = selectCount(baseMapper, s -> s.eq(BasePojo::getId, tgDeductionId));
        Assert.state(null != count && 0 < count, "未找到指定信息，请刷新重试");
        TgDeduction bo = new TgDeduction();
        bo.setId(tgDeductionId);
        bo.setIsDel(1);
        BasePojo.setBase(user.getId().longValue(), false, bo);
        updateById(bo);
    }



    private static boolean checkOverlap(List<TgDeductionChild> ranges) {
        int n = ranges.size();
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                TgDeductionChild range1 = ranges.get(i);
                TgDeductionChild range2 = ranges.get(j);
                if (range1.overlapsWith(range2)) {
                    return true; // 存在重叠的情况
                }
            }
        }
        return false; // 没有重叠的情况
    }


    private static void orderDeduction(List<TgDeductionChild> ranges) {
        // 自定义比较器，按时间排序
        Comparator<TgDeductionChild> timeComparator = new Comparator<TgDeductionChild>() {
            @Override
            public int compare(TgDeductionChild timeRange1, TgDeductionChild timeRange2) {
                LocalTime startTime1 = LocalTime.parse(timeRange1.getStartTime());
                LocalTime startTime2 = LocalTime.parse(timeRange2.getEndTime());
                return startTime1.compareTo(startTime2);
            }
        };

        // 使用自定义比较器进行排序
        Collections.sort(ranges, timeComparator);
    }

    public static void main(String[] args) {
        List<String> timeRanges = new ArrayList<>();
        timeRanges.add("05:00:00-23:59:59");
        timeRanges.add("00:00:00-01:59:59");
        timeRanges.add("02:00:00-04:59:59");

        // 自定义比较器，按时间排序
        Comparator<String> timeComparator = new Comparator<String>() {
            @Override
            public int compare(String timeRange1, String timeRange2) {
                LocalTime startTime1 = LocalTime.parse(timeRange1.split("-")[0]);
                LocalTime startTime2 = LocalTime.parse(timeRange2.split("-")[0]);
                return startTime1.compareTo(startTime2);
            }
        };

        // 使用自定义比较器进行排序
        Collections.sort(timeRanges, timeComparator);

        // 输出排序后的结果
        for (String timeRange : timeRanges) {
            System.out.println(timeRange);
        }
    }


}
